package com.example.springboot.web;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Hashtable;

@Component
// 自定义连接地址
@ServerEndpoint("/ws/{id}")  // 地址参数 id 客户端的唯一表示
public class MyWebSocket {
    // Hashtable 用来存放每个客户端对应的 id : Session 对象。
    private static Hashtable<String, Session> webSocketMap = new Hashtable<>();
    // 每次有客户端连接上来, WebSocket 都会为其创建一个 MyWebSocket 对象
    // 替代方案: redis , mysql
    // 连接建立成功调用的方法
    @OnOpen
    public void onOpen(@PathParam("id") String id, Session session) {
        // HashMap  vs Hashtable (线程安全) ?
        webSocketMap.put(id, session);
        // 添加会话属性, 存入id
        session.getUserProperties().put("id", id);
        System.out.println(id + "上线了!");
    }
    // 连接关闭调用的方法
    @OnClose
    public void onClose(Session session) {
        String id = (String) session.getUserProperties().get("id");
        webSocketMap.remove(id);
        System.out.println(id + "下线了!");
    }
    // 收到客户端消息后调用的方法
    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        // 接收到消息后, 将消息群发给其他用户
        String id = (String) session.getUserProperties().get("id");
        System.out.println(message);
        for (Session other : webSocketMap.values()) {
            if(other.equals(session) == false){
                other.getBasicRemote().sendText(message);
            }
        }
    }

    @Scheduled(cron = "0/15 * * * * ?")
    public void sendTimeMsg() throws IOException {
        String msg = "系统消息: 天气预报...";
        for (Session s : webSocketMap.values()) {
            s.getBasicRemote().sendText(msg);
        }
    }
}
